#include "GPTool.h"

void EnCode(const unsigned long* const v,
	unsigned long* const w,
	const unsigned long* const k)
{
	unsigned long y = v[0];
	unsigned long z = v[1];
	unsigned long sum = 0;
	unsigned long delta = 0x9E3779B9;
	unsigned long n = 32;

	while(n-- > 0)
	{
		y += (z<<4^z>>5) + z^ sum + k[sum & 3];
		sum += delta;
		z += (y<<4 ^ y>>5) + y ^ sum + k[sum>>11 & 3];
	}

	w[0] = y;
	w[1] = z;
}

void DeCode(const unsigned long* const v,
	unsigned long* const w,
	const unsigned long* const k)
{
	unsigned long y = v[0];
	unsigned long z = v[1];
	unsigned long sum = 0xC6EF3720;
	unsigned long delta = 0x9E3779B9;
	unsigned long n = 32;

	while(n-- > 0)
	{
		z -= (y<<4 ^ y>>5) + y ^ sum + k[sum>>11 & 3];
		sum -= delta;
		y -= (z<<4 ^ z>>5) + z^ sum + k[sum&3];
	}

	w[0] = y;
	w[1] = z;
}

UINT64 GetCPUTime(void)
{
	unsigned int uiTimeHi;
	unsigned int uiTimeLow;

	_asm
	{
		rdtsc
			mov uiTimeHi,edx;
		mov uiTimeLow,eax;
	}

	return ((UINT64)uiTimeHi<<32) + (UINT64)uiTimeLow;
}

UINT64 GetCPUTime2(void)
{
	_asm RDTSC;
}

float g_fCos_Look[MAX_ANGLE];
float g_fSin_Look[MAX_ANGLE];
void InitialCosSinLook(void)
{
	for(int i = 0;i < MAX_ANGLE;++i)
	{
		float fAngle = MY_2PI * i / MAX_ANGLE;
		g_fCos_Look[i] = cos(fAngle);
		g_fSin_Look[i] = sin(fAngle);
	}
}

float FastDistance2D(float fdX,float fdY)
{
	int iX = (int)fabs(fdX);
	int iY = (int)fabs(fdY);

	int iMin = min(iX,iY);

	return (float)(iX + iY - (iMin >> 1) - (iMin >> 2) + (iMin >> 4));
}

float FastDistance3D(float fdX,float fdY,float fdZ)
{
	int iX,iY,iZ;

	iX = (int)fabs(fdX) * 1024;
	iY = (int)fabs(fdY) * 1024;
	iZ = (int)fabs(fdZ) * 1024;

	if(iY < iX)
	{
		Swap(iX,iY);
	}
	if(iZ < iY)
	{
		Swap(iY,iZ);
	}
	if(iY < iX)
	{
		Swap(iX,iY);
	}

	int iDis = (iZ + 11 * (iY >> 5) + (iX >> 2));
	return ((float)(iDis >> 10));
}

float Distance2D(float fdX,float fdY)
{
	return sqrt(fdX * fdX + fdY * fdY);
}

float Distance2D2(float fdX,float fdY)
{
	return (fdX * fdX + fdY * fdY);
}

float Distance3D(float fdX,float fdY,float fdZ)
{
	return sqrt(fdX * fdX + fdY * fdY + fdZ * fdZ);
}

void MyOutputDebugString(WCHAR* fmt,...)
{
	WCHAR acOut[512] = {0};
	va_list arglist;
	va_start(arglist,fmt);
	wvsprintf(acOut,fmt,arglist);
	va_end(arglist);

	OutputDebugString(acOut);
}